package com.dartfar.workflow.service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.dom4j.Element;
import org.jbpm.api.RepositoryService;
import org.jbpm.pvm.internal.repository.DeploymentImpl;
import org.springframework.stereotype.Component;

import com.dartfar.base.dao.DaoUtil;
import com.dartfar.base.service.BaseServiceImpl;
import com.dartfar.util.EntityUtils;
import com.dartfar.util.FileUtils;
import com.dartfar.util.PathUtil;
import com.dartfar.workflow.constant.WorkflowStatusVar;
import com.dartfar.workflow.constant.WorkflowDeployVar;
import com.dartfar.workflow.helper.WorkflowHelper;
import com.dartfar.workflow.model.WorkflowDeployTask;
import com.dartfar.workflow.model.WorkflowDeployment;
import com.dartfar.workflow.model.WorkflowProcessFunMount;
import com.dartfar.workflow.model.WorkflowTaskFunMount;

@Component("workflowDeploymentService")
public class WorkflowDeploymentServiceImpl extends BaseServiceImpl<WorkflowDeployment> implements WorkflowDeploymentService {

	static Logger logger = Logger.getLogger(WorkflowDeploymentServiceImpl.class);
	
	@Resource
	private DaoUtil<WorkflowDeployment> workflowDeploymentDaoUtil;
	@Resource
	private DaoUtil<WorkflowProcessFunMount> workflowProcessFunMountDaoUtil;
	@Resource
	private RepositoryService repositoryService;
	
	/**
	 * 部署流程
	 * @param filePath
	 * @param d
	 * @return
	 */
	@Override
	public void deployment(String fileName, String filePath, int id) {
		// TODO Auto-generated method stub
		File file = new File(filePath);
		//根据文件名称部署流程
		String deployId = repositoryService.createDeployment().addResourceFromFile(file).deploy();
		//得到已部署的流程定义对象
		DeploymentImpl deployementImpl = (DeploymentImpl) repositoryService.createDeploymentQuery().deploymentId(deployId).uniqueResult();
		//构建功能流程挂接表
		WorkflowProcessFunMount workflowProcessFunMount = null;
		WorkflowDeployment workflowDeployment = null;
		if(id != 0){
			workflowDeployment = get(id);
			logger.info("workflowDeployment对象: " + workflowDeployment);
			workflowProcessFunMount = (WorkflowProcessFunMount)workflowProcessFunMountDaoUtil.get("from WorkflowProcessFunMount w where w.deployId = " + workflowDeployment.getDeployId());
			logger.info("workflowProcessFunMount对象: " + workflowProcessFunMount);
			if(buildWorkflowDeployment(workflowDeployment, filePath, deployementImpl, workflowProcessFunMount)){
				//持久化自己WorkflowDeployment
				workflowProcessFunMountDaoUtil.update(workflowProcessFunMount);
				workflowDeploymentDaoUtil.update(workflowDeployment);
			}
		}else{
			workflowDeployment = new WorkflowDeployment();
			workflowProcessFunMount = new WorkflowProcessFunMount();
			if(buildWorkflowDeployment(workflowDeployment, filePath, deployementImpl, workflowProcessFunMount)){
				//持久化自己WorkflowDeployment
				workflowProcessFunMountDaoUtil.save(workflowProcessFunMount);
				workflowDeploymentDaoUtil.save(workflowDeployment);
			}
		}
		
	}
	
	
	/**
	 * 构建出流程定义实体对象
	 * @param filePath
	 * @param d
	 * @return
	 */
	public Boolean buildWorkflowDeployment(WorkflowDeployment workflowDeployment, String filePath, DeploymentImpl d, WorkflowProcessFunMount workflowProcessFunMount){
		//初始化辅助类
		WorkflowHelper wfh = new WorkflowHelper(filePath);
		//拿到流程定义节点
		Element process = wfh.getProcessNode();
		//设置部署ID
		workflowDeployment.setDeployId(d.getId());
		//设置文件路径
		workflowDeployment.setFilePath(filePath);
		//流程定义的name
		workflowDeployment.setProcessName(process.attributeValue("name"));
		//流程定义的key
		workflowDeployment.setProcessKey(process.attributeValue("key"));
		//流程定义的描述
		workflowDeployment.setDescript(wfh.getDescript());
		//流程定义版本
		workflowDeployment.setVersion(d.getProcessDefinitionVersion(workflowDeployment.getProcessName()));
		System.out.println("version: " + d.getProcessDefinitionVersion(workflowDeployment.getProcessName()));
		//流程定义ID
		workflowDeployment.setProcessDefinitionId(d.getProcessDefinitionId(workflowDeployment.getProcessName()));
		//流程任务节点
		List<WorkflowDeployTask> workflowTasks = buildWorkflowDeployTask(filePath, workflowDeployment);
		workflowDeployment.setWorkflowDeployTasks(workflowTasks);
		
		//流程功能挂接信息
		workflowProcessFunMount.setDeployId(workflowDeployment.getDeployId());
		workflowProcessFunMount.setProcessDefinitionId(workflowDeployment.getProcessDefinitionId());
		workflowProcessFunMount.setProcessKey(workflowDeployment.getProcessKey());
		workflowProcessFunMount.setProcessName(workflowDeployment.getProcessName());
		workflowProcessFunMount.setVersion(workflowDeployment.getVersion());
		if(EntityUtils.isNotNull(wfh.getVariableNode(WorkflowDeployVar.BO_TYPE)) && EntityUtils.isNotNull(wfh.getVariableNode(WorkflowDeployVar.BO_ID_NAME)) && EntityUtils.isNotNull(wfh.getVariableNode(WorkflowDeployVar.ROLLBACKABLE)) && EntityUtils.isNotNull(wfh.getVariableNode(WorkflowDeployVar.WITHDRAWABLE))){
			workflowProcessFunMount.setWithrawAble(wfh.getVariableNode(WorkflowDeployVar.BO_URL).attributeValue("value"));
			workflowProcessFunMount.setModelName(wfh.getVariableNode(WorkflowDeployVar.BO_TYPE).attributeValue("value"));
			workflowProcessFunMount.setModelIdName(wfh.getVariableNode(WorkflowDeployVar.BO_ID_NAME).attributeValue("value"));
			workflowProcessFunMount.setRollBackAble(wfh.getVariableNode(WorkflowDeployVar.ROLLBACKABLE).attributeValue("value"));
			workflowProcessFunMount.setWithrawAble(wfh.getVariableNode(WorkflowDeployVar.WITHDRAWABLE).attributeValue("value"));
		}else{
			System.out.println("文件变量设置错误，请检查文件");
			return false;
		}
		
		//logger.info("workflowProcessFunMountSize: " + workflowProcessFunMount.getWorkflowTaskFunMounts().size());
		
		workflowProcessFunMount.setMountStatus(WorkflowStatusVar.MOUNTSTATUS_NO);
		workflowProcessFunMount.setWorkflowTaskFunMounts(buildTaskFunMounts(workflowTasks, workflowProcessFunMount));
		return true;
	}

	
	/**
	 * 流程定义出任务节点的集合对象
	 * @param filePath
	 * @param workflowDeployment
	 * @return
	 */
	public List<WorkflowDeployTask> buildWorkflowDeployTask(String filePath, WorkflowDeployment workflowDeployment){
		List<WorkflowDeployTask> workflowTasks = new ArrayList<WorkflowDeployTask>();
		//初始化辅助类
		WorkflowHelper wfh = new WorkflowHelper(filePath);
		
		List<WorkflowDeployTask> oldTasks = workflowDeployment.getWorkflowDeployTasks();
		
		//得到所有任务的节点对象集合
		List nodes = wfh.getTaskNodes();
		if(EntityUtils.isNotNull(nodes)){
			for(int i=0;i<nodes.size();i++){
				WorkflowDeployTask workflowTask = new WorkflowDeployTask();
				Element node = (Element)nodes.get(i);
				
				//判断oldTasks是否为空
				if(EntityUtils.isNotNull(oldTasks)){
					//遍历上个版本的任务节点对象集合
					for(WorkflowDeployTask oldTask : oldTasks){
						//如果任务节点存在
						if(oldTask.getTaskName().equalsIgnoreCase(node.attributeValue("name"))){
							logger.info("TaskName： " + oldTask.getTaskName() + " 存在");
							//把上一版本的任务节点对象赋值到新的对象中
							workflowTask = oldTask;
							//workflowTask.setId(oldTask.getId());
							break;
						}
					}
				}
				
				//workflowTask.setDeployId(workflowDeployment.getDeployId());
				workflowTask.setTaskName(node.attributeValue("name"));
				workflowTask.setAssigneType(node.attributeValue("assigneType"));
				workflowTask.setAssignees(node.attributeValue("assignees"));
				workflowTask.setAssigneRoles(node.attributeValue("roles"));
				workflowTask.setWorkflowDeployment(workflowDeployment);
				workflowTasks.add(workflowTask);
				
			}
		}
		return workflowTasks;
	}
	
	
	/**
	 * 任务挂接对象集合
	 * @param workflowDeployTasks
	 * @param workflowProcessFunMount
	 * @return
	 */
	public List<WorkflowTaskFunMount> buildTaskFunMounts(List<WorkflowDeployTask> workflowDeployTasks,WorkflowProcessFunMount workflowProcessFunMount){
		List<WorkflowTaskFunMount> taskFuncMount = new ArrayList<WorkflowTaskFunMount>();
		List<WorkflowTaskFunMount> oldTaskMount = workflowProcessFunMount.getWorkflowTaskFunMounts();
		//遍历
		for(WorkflowDeployTask workflowDeployTask : workflowDeployTasks){
			WorkflowTaskFunMount taskFun = null;
			logger.info("workflowDeployTask: " + workflowDeployTask.getTaskName() + "  ID: " + workflowDeployTask.getId());
			if(EntityUtils.isNotNull(oldTaskMount)){
				for(WorkflowTaskFunMount oldTask : oldTaskMount){
					logger.info("oldTask: " + oldTask.getTaskNodeName() + "  ID: " + oldTask.getTaskNodeId());
					if(oldTask.getTaskNodeName().equalsIgnoreCase(workflowDeployTask.getTaskName())){
						logger.info("taskFun: " + oldTask.getTaskNodeName());
						taskFun = oldTask;
						break;
					}
				}
			}
			
			if(taskFun == null){
				taskFun = new WorkflowTaskFunMount();
			}
			taskFun.setDeployId(workflowProcessFunMount.getDeployId());
			taskFun.setProcessDefinitionId(workflowProcessFunMount.getProcessDefinitionId());
			logger.info("TaskNodeId: " + workflowDeployTask.getId());
			logger.info("TaskNodeName: " + workflowDeployTask.getTaskName());
			taskFun.setTaskNodeId(workflowDeployTask.getId());
			taskFun.setTaskNodeName(workflowDeployTask.getTaskName());
			taskFun.setWorkflowProcessFunMount(workflowProcessFunMount);
			taskFuncMount.add(taskFun);
		}
		return taskFuncMount;
	}

	/**
	 * 查找workflowFiles目录下工作流文件总数
	 */
	@Override
	public Long getWorkflowFileCount(){
		List<String> filePathList = new ArrayList<String>();
		FileUtils.list(PathUtil.getWorkflowFilesPath(), ".jpdl.xml", false, filePathList);
		Integer size = filePathList.size();
		return size.longValue();
	}

	/**
	 * 查找到WorkflowFiles目录下的所有工作流文件信息
	 * @param start
	 * @param limit
	 * @return
	 */
	@Override
	public List<WorkflowDeployment> findWorkflowFile(Integer pageNo, Integer pageSize) {
		// TODO Auto-generated method stub
		List<String> filePathList = new ArrayList<String>();
		FileUtils.list(PathUtil.getWorkflowFilesPath(), ".jpdl.xml", false, filePathList);
		Integer size = filePathList.size();
		pageNo = (pageNo - 1);
		pageSize = pageNo + pageSize;
		if(pageSize >= size){
			pageSize = size;
		}
		filePathList = filePathList.subList(pageNo, pageSize);
		List<WorkflowDeployment> workflowDeployments = new ArrayList<WorkflowDeployment>();
		for(String filePath : filePathList){
			WorkflowDeployment workflowDeployment = new WorkflowDeployment();
			WorkflowHelper wfh = new WorkflowHelper(filePath);
			Element process = wfh.getProcessNode();
			//设置文件路径
			workflowDeployment.setFileName(filePath.substring(PathUtil.getWorkflowFilesPath().length()));
			workflowDeployment.setFilePath(filePath);
			//流程定义的name
			workflowDeployment.setProcessName(process.attributeValue("name"));
			//流程定义的key
			workflowDeployment.setProcessKey(process.attributeValue("key"));
			//流程定义的描述
			workflowDeployment.setDescript(wfh.getDescript());
			//设置流程定义ID
			List<WorkflowDeployment> deploys = workflowDeploymentDaoUtil.getList("from WorkflowDeployment w where w.processName = '" + workflowDeployment.getProcessName() + "' and w.processKey = '" + workflowDeployment.getProcessKey() + "' order by w.version desc");
			if(deploys != null && deploys.size() > 0){
				WorkflowDeployment deploy = deploys.get(0);				
				workflowDeployment.setId(deploy.getId());
				workflowDeployment.setVersion(deploy.getVersion());
				workflowDeployment.setProcessDefinitionId(deploy.getProcessDefinitionId());
			}
			workflowDeployments.add(workflowDeployment);
		}
		return workflowDeployments;
	}

	@Override
	public void clearDeployment(WorkflowDeployment deploy) {
		// TODO Auto-generated method stub
		
	}
	
}
